#ifndef CONNECTIONSMANAGER_H
#define CONNECTIONSMANAGER_H
#include "torrentpeerdata.h"
#include "torrentconnection.h"
#include "torrentpeerobserver.h"

#include "metainfo.h"


class QDir;

class FileWriter;

class TorrentFilePiece
{
public:
    enum State
    {
        NotDownloading = 0,
        DownloadingInProgress,
        DownloadFinished
    };
    TorrentFilePiece(int _pieceLength, int _blockSize);
    int downloadNextBlock();
    int getFirstDownloadingBlock();
    void setBlockDownloaded(int blockIndex);
    void setBlockNotDownloading(int blockIndex);
    int getBlockLength(int blockIndex);    
    void setInvalid();
    State getState() const;
private:
    int pieceLength;
    int blockSize;
    int blocksCount;
    QList<State> blocks;
    State pieceState;
};

class ConnectionsManager : public QObject,
                           public TorrentPeerObserver
{
    Q_OBJECT
public:
    ConnectionsManager(QObject* parent);
    ~ConnectionsManager();
  void startFile(MetaInfo& fileInfo,  const QByteArray& infoHash, const QDir& dir);
  void stopDownloadingFile();

public slots:
    void peersDataReceived(QList<TorrentPeerData>& data);
private slots:
    void updateTransferRate();
signals:
    void error(const QString& errorMessage);
    void downloadCompleted();
    void downloadsTableChanged(QMap<TorrentConnection*, QPair <int, int> >*);
    void transferRateUpdated(double transferRate);


private:
        void requestNextDownload(TorrentConnection& peer);
        TorrentConnection* getIdlePeer();
        void requestDownload(TorrentConnection& peer, int pieceIndex, int blockIndex);
        void endGameStuff();
        //TorrentPeerObserver methods
        void unchokeReceived(TorrentConnection &peer);
        void chokeReceived(TorrentConnection &peer);
        void pieceReceived(TorrentConnection &peer, const QByteArray& piece);
        //
        bool checkAllPiecesDownloaded();
        bool checkDataValidity();
private:
    QList<TorrentConnection*> connectionsList;
    MetaInfo fileMetaInfo;    
    QList<TorrentFilePiece> filePieces;
    qint64 totalBytesDownloaded;
    QTimer* transferTimer;
    QTime* elapsedTime;
    double transferRate;
    FileWriter* fileWriter;
    QMap< TorrentConnection*, QPair<int, int> >* downloadsMap;
};

#endif // CONNECTIONSMANAGER_H
